<?php

declare(strict_types=1);

namespace App\Middleware;

use App\Lib\Redis;
use App\Lib\Token;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Hyperf\HttpServer\Contract\ResponseInterface as HttpResponse;

class AdminMiddleware implements MiddlewareInterface {
    /**
     * @var ContainerInterface
     */
    protected $container;
    /**
     * @var ResponseInterface
     */
    protected $response;
    /**
     * @var Token
     */
    protected $token;

    public function __construct(ContainerInterface $container, HttpResponse $response, Token $token) {
        $this->container = $container;
        $this->response = $response;
        $this->token = $token;
    }

    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface {
        $authorize = $request->getHeaderLine('authorize');
        $admin = $this->token->adminVerify($authorize);
        switch ($admin) {
            case 'invalid':
                return $this->exit(10001, '未登录');
            case 'other':
                return $this->exit(10004, '其他设备登录');
            default:
                $request = $request->withAttribute('admin', $admin);
        }
        // 验证权限
        /** @var array $admin */
        if ($admin['id'] != 1 && $this->authCheck($admin['id'], $request)) {
            return $this->exit(10006, '无访问权限');
        }
        return $handler->handle(\Hyperf\Utils\Context::set(ServerRequestInterface::class, $request));
    }

    private function exit($code, $msg) {
        return $this->response->json(resData($code, $msg, new \stdClass()));
    }

    /**
     * 权限验证 false 表示验证通过
     * @param $admin array 用户信息
     * @param $request \Psr\Http\Message\ServerRequestInterface 路径
     * @return bool
     */
    private function authCheck($admin, $request) {
        $path = trim($request->getUri()->getPath(), '/');
        // 通用权限
        $noVerify = ['a/login_info', 'a/ch_pwd'];
        if (in_array($path, $noVerify)) {
            return true;
        }
        $path = $request->getMethod() . '|' . $path;
        $redis = Redis::get();
        foreach ($admin['rid'] as $role) {
            if ($redis->hGet("ar:{$role}", $path)) {
                return false;
            }
        }
        return true;
    }
}
